package org.dromara.system.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.SerializationUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.ArchivesBo;
import org.dromara.system.domain.bo.SkyBagBo;
import org.dromara.system.domain.bo.SkyRelationshipBo;
import org.dromara.system.domain.bo.WbCandidateListBo;
import org.dromara.system.domain.vo.*;
import org.dromara.system.mapper.*;
import org.dromara.system.service.IWbCandidateService;
import org.dromara.system.service.SkyClientService;
import org.dromara.system.utils.SkyEyeProperties;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
@Slf4j
public class WbCandidateServiceImpl implements IWbCandidateService {

    private final WbCandidateListMapper candidateListMapper;
    private final WbCompanyInfoMapper companyInfoMapper;
    private final SkyAbnornalMapper skyAbnornalMapper;
    private final SkyHumanDishonestMapper dishonestMapper;
    private final SkyPunishmentMapper punishmentMapper;
    private final SkyNodeMapper nodeMapper;
    private final SkyRelationshipMapper relationshipMapper;
    private final SkyClientService skyClientService;

    /**
     * 开始分析数据，调用天眼查进行更新企业数据内容
     * @param candidateId 标ID，即项目ID
     */
    @Override
    public void startAnalysis(Long candidateId) {
        WbCandidateListBo bo = new WbCandidateListBo();
        bo.setCandidateId(candidateId);

        //查询所有分包数据中的供应商
        List<String> list = candidateListMapper.queryAllCandidate(bo);

        for(String candidate : list) {
            long start = System.currentTimeMillis();
            processList(candidate);
            long end = System.currentTimeMillis();
            System.out.println(candidate + "处理耗时 = " + (end - start) + "ms");
        }

        System.out.println("分析执行完毕！");
    }

    /**
     * 创建任务
     * @param list 列表
     * @return 多线程任务
     */
    private void processList(String candidate) {
        //处理企业异常信息
        mergeCompanyInfoData(candidate);
        mergeAbnormalData(candidate);
        mergeDishonestData(candidate);
        mergePunishmentData(candidate);
        mergeCompanyFaceData(candidate);
    }

    /**
     * 查询股权关系
     */
    @Override
    public List<SkyBagVo> queryShareholding(SkyBagBo bo) {
        String candidateCode = queryCandidateCode(bo);

        //未找到包数据时，返回空
        if(StringUtils.isEmpty(candidateCode)) {
            return new ArrayList<>();
        }

        //处理查询条件
        bo.setCandidateCode("'" + candidateCode.replaceAll(",", "','") + "'");
        //组装关系
        List<SkyRelationshipVo> relationshipVoList = assembleRelation(bo);

        List<SkyBagVo> result = new ArrayList<>();
        SkyBagVo bagVo = new SkyBagVo();
            bagVo.setSkyNodeVoList(assembleNode(bo.getCandidateCode(), relationshipVoList));
            bagVo.setSkyRelationshipVoList(relationshipVoList);
        result.add(bagVo);

        return result;
    }

    /**
     * 查询关系列表，为导出做准备
     * @param bo 关系类
     * @return 列表
     */
    @Override
    public List<SkyRelationshipVo> queryRelationship(SkyRelationshipBo bo) {
        WbCandidateListBo candidateListBo = new WbCandidateListBo();
        candidateListBo.setCandidateId(bo.getCandidateId());

        //查询所有的数据
        List<WbCandidateListVo> list = candidateListMapper.queryBagData(candidateListBo);

        //为空直接返回
        if(list.isEmpty()) {
            return new ArrayList<>();
        }

        List<SkyRelationshipVo> lastList = new ArrayList<>();

        //遍历标中所有分包数据
        for(WbCandidateListVo vo : list) {
            //分包查询条件
            SkyBagBo bagBo = new SkyBagBo();
            bagBo.setCandidateCode("'" + vo.getCandidateCode().replaceAll(",", "','") + "'");
            //处理关系列表
            List<SkyRelationshipVo> childList = assembleExportData(bagBo);

            //把包名设置进去，为了展示使用
            lastList.addAll(childList.stream().peek(data -> {
                data.setBagName(vo.getBagName());
                data.setSubStandardName(vo.getSubStandardName());
            }).toList());
        }

        return lastList;
    }

    @Override
    public List<WbCandidateListRiskVo> queryVendorList(WbCandidateListBo bo) {
        WbCandidateListBo candidateListBo = new WbCandidateListBo();
        candidateListBo.setCandidateId(bo.getCandidateId());

        //查询所有的数据
        List<WbCandidateListVo> list = candidateListMapper.queryBagData(candidateListBo);

        //为空直接返回
        if(list.isEmpty()) {
            return new ArrayList<>();
        }

        List<WbCandidateListRiskVo> lastList = new ArrayList<>();

        //遍历标中所有分包数据
        for(WbCandidateListVo vo : list) {
            WbCandidateListBo listBo = SerializationUtils.clone(bo);
            listBo.setCandidateCode("'" + vo.getCandidateCode().replaceAll(",", "','") + "'");
            List<WbCandidateListRiskVo> vendorList = candidateListMapper.queryRiskList(listBo);

            if(vendorList.isEmpty()) {
                continue;
            }

            Map<String, WbCandidateListRiskVo> map = vendorList.stream().collect(Collectors.toMap(WbCandidateListRiskVo::getCandidateCode, v -> v));

            //分包查询条件
            SkyBagBo bagBo = new SkyBagBo();
            bagBo.setCandidateCode("'" + vo.getCandidateCode().replaceAll(",", "','") + "'");
            lastList.addAll(assembleVendorData(bagBo, map));
        }

        return lastList;
    }

    /**
     * 查询包中包含的供应商code
     * @param bo 查询条件
     * @return String Code
     */
    private String queryCandidateCode(SkyBagBo bo) {
        WbCandidateListBo candidateListBo = new WbCandidateListBo();
        candidateListBo.setCandidateId(bo.getCandidateId());
        candidateListBo.setBagName(bo.getBagName());

        List<WbCandidateListVo> list = candidateListMapper.queryBagData(candidateListBo);

        //未找到数据返回空字符串
        if(list.isEmpty()) {
            return "";
        }

        //获取包中所有公司编码
        return list.get(0).getCandidateCode();
    }

    /**
     * 组装节点
     * @param candidateCode 编码
     * @param relationshipVoList 关系列表
     */
    private List<SkyNodeVo> assembleNode(String candidateCode, List<SkyRelationshipVo> relationshipVoList) {
        List<String> nodeList = new ArrayList<>(Arrays.stream(candidateCode.replaceAll("'","").split(",")).toList());

        //当关系存在时，将关系中的节点存入nodeList一起查询
        if(relationshipVoList != null && !relationshipVoList.isEmpty()) {
            for(SkyRelationshipVo vo : relationshipVoList) {
                if(!nodeList.contains(vo.getStartNode())) {
                    nodeList.add(vo.getStartNode());
                }

                if(!nodeList.contains(vo.getEndNode())) {
                    nodeList.add(vo.getEndNode());
                }
            }
        }

        String nodes = String.join("','", nodeList);
        SkyBagBo bo = new SkyBagBo();
        bo.setCandidateCode("'" + nodes + "'");

        return nodeMapper.selectNodeList(bo);
    }

    /**
     * 组装关系
     * @param bo 查询条件
     */
    private List<SkyRelationshipVo> assembleRelation(SkyBagBo bo) {
        List<SkyRelationshipVo> relationshipVoList = new ArrayList<>();
        List<SkyRelationshipVo> startRelationshipList = relationshipMapper.selectRelationshipListByStartNode(bo);
        List<SkyRelationshipVo> endRelationshipList = relationshipMapper.selectRelationshipListByEndNode(bo);
        //包内企业编码
        List<String> nodeList = new ArrayList<>(Arrays.stream(bo.getCandidateCode().replaceAll("'","").split(",")).toList());

        for (SkyRelationshipVo start : startRelationshipList) {
            //当关系节点的下一步包含在包内企业编码时，关系节点可以展示
            if (nodeList.contains(start.getEndNode())) {
                relationshipVoList.add(start);
                continue;
            }

            Iterator<SkyRelationshipVo> endIt = endRelationshipList.iterator();

            while (endIt.hasNext()) {
                SkyRelationshipVo end = endIt.next();

                //当关系节点的下一步和关系节点的上一步相等时，关系节点可以展示
                if (start.getEndNode().equals(end.getStartNode())) {
                    relationshipVoList.add(start);
                    relationshipVoList.add(end);

                    //移除是为了下一次循环可以少一次
                    endIt.remove();
                }
            }
        }

        return relationshipVoList;
    }

    /**
     * 组装导出数据
     * @param bo 查询条件
     */
    private List<SkyRelationshipVo> assembleExportData(SkyBagBo bo) {
        List<SkyRelationshipVo> relationshipVoList = new ArrayList<>();
        List<SkyRelationshipVo> startRelationshipList = relationshipMapper.selectRelationshipListByStartNode(bo);
        List<SkyRelationshipVo> endRelationshipList = relationshipMapper.selectRelationshipListByEndNode(bo);
        //包内企业编码
        List<String> nodeList = new ArrayList<>(Arrays.stream(bo.getCandidateCode().replaceAll("'","").split(",")).toList());

        for (SkyRelationshipVo start : startRelationshipList) {
            //当关系节点的下一步包含在包内企业编码时，关系节点可以展示
            if (nodeList.contains(start.getEndNode())) {
                //开始节点对应的节点是结束节点
                relationshipVoList.add(assembleName(start, null, "1"));
                continue;
            }

            for (SkyRelationshipVo end : endRelationshipList) {
                //当关系节点的下一步和关系节点的上一步相等时，关系节点可以展示
                if (start.getEndNode().equals(end.getStartNode())) {
                    System.out.println(start.getStartName() + "; " + start.getEndName() + "; " + end.getStartName() + "; " + end.getEndName());
                    relationshipVoList.add(assembleName(start, end, "2"));
                }
            }
        }

        List<String> needRemoveEnd = new ArrayList<>();

        for (SkyRelationshipVo start : endRelationshipList) {

            for (SkyRelationshipVo end : endRelationshipList) {
                //同一条数据，执行下一条
                if (start.getStartNode().equals(end.getStartNode()) && start.getEndNode().equals(end.getEndNode())) {
                    continue;
                }

                //已经排除的节点
                if (needRemoveEnd.contains(end.getStartNode() + "-" + end.getEndNode())) {
                    continue;
                }

                //当关系节点的下一步和关系节点的上一步相等时，关系节点可以展示
                if (start.getStartNode().equals(end.getStartNode())) {
                    System.out.println(start.getStartName() + "; " + start.getEndName() + "; " + end.getStartName() + "; " + end.getEndName());
                    relationshipVoList.add(assembleName(start, end, "3"));
                    //移除是为了下一次循环可以少一次
                    needRemoveEnd.add(end.getStartNode() + "-" + end.getEndNode());
                }
            }
        }

        return relationshipVoList;
    }

    /**
     * 组装关系
     * @param data 开始节点
     * @param end 结束节点
     * @param type 关系 1：父子 2:祖孙 3：同一父亲
     * @return 关系
     */
    private SkyRelationshipVo assembleName(SkyRelationshipVo data, SkyRelationshipVo end, String type) {
        SkyRelationshipVo start = SerializationUtils.clone(data);
        String name = null;

        switch (type) {
            case "1" : name = " -" + start.getName() + "-> "; break;
            case "2" : name = " -" + start.getName() + "-> " + end.getStartName() + " -" + end.getName() + "-> ";
                start.setEndName(end.getEndName());
                start.setEndNode(end.getEndNode());
                break;
            case "3" : name = " <-" + start.getName() + "- " + end.getStartName() + " -" + end.getName() + "-> ";
                start.setEndName(end.getEndName());
                start.setEndNode(end.getEndNode());
                start.setStartName(data.getEndName());
                start.setStartNode(data.getEndNode());
                break;
        }

        start.setName(name);

        return start;
    }

    /**
     * merge企业信息
     * @param candidate 企业名称
     */
    private void mergeCompanyInfoData(String candidate) {
        ArchivesBo bo = new ArchivesBo();
        bo.setKeyword(candidate);
        List<WbCompanyInfo> voList = companyInfoMapper.selectList(new LambdaQueryWrapper<WbCompanyInfo>().eq(true, WbCompanyInfo::getName, candidate));

        //如果为空或者没有更新天眼查数据
        if (!voList.isEmpty() && null != voList.get(0).getSkyId()) {//添加数据
            return;
        }

        WbCompanyInfo info = voList.isEmpty() ? null : voList.get(0);
        JSONObject data = skyClientService.query(bo, SkyEyeProperties.COMPANY_INFO);

        if(data != null && !data.isEmpty()) {
            companyInfoMapper.insertOrUpdate(jsonToCompanyInfo(data, info));
        }
    }

    /**
     * merge经营异常
     * @param candidate 企业名称
     */
    public void mergeAbnormalData(String candidate) {
        ArchivesBo bo = new ArchivesBo();
        bo.setKeyword(candidate);

        List<JSONObject> jo = new ArrayList<>();
        jo.addAll(queryAbnormal(bo, SkyEyeProperties.ABNORMAL, "0"));
        jo.addAll(queryAbnormal(bo, SkyEyeProperties.ILLEGAL_INFO, "1"));

        if(!jo.isEmpty()) {
            ObjectMapper mapper = new ObjectMapper();

            try {
                List<SkyAbnornal> list = mapper.readValue(jo.toString(), new TypeReference<>() {});
                //把以前的数据删除, 通过企业名称
                skyAbnornalMapper.deleteByCompanies(candidate);
                //重新插入新数据
                list = list.stream().peek(data -> data.setCompanyName(candidate)).toList();
                skyAbnornalMapper.insertBatch(list);
            } catch (Exception e) {
                log.error("获取经营异常数据失败");
            }
        }
    }

    /**
     * merge不诚实信息
     * @param candidate 企业名称
     */
    public void mergeDishonestData(String candidate) {
        ArchivesBo bo = new ArchivesBo();
        bo.setName(candidate);

        JSONObject jo = skyClientService.query(bo, SkyEyeProperties.DISHONEST);

        if (jo.isEmpty() || !jo.containsKey("total") || jo.getInt("total") == 0) {
            return;
        }

        ObjectMapper mapper = new ObjectMapper();

        try {
            List<SkyHumanDishonest> list = mapper.readValue(jo.toString(), new TypeReference<>() {});
            //把以前的数据删除
            dishonestMapper.deleteByCompanies(candidate);
            //重新插入新数据
            list = list.stream().peek(data -> data.setCompanyName(candidate)).toList();
            dishonestMapper.insertBatch(list);
        } catch (Exception e) {
            log.error("获取失信被执行人数据失败");
        }
    }

    /**
     * merge行政处罚
     * @param candidate 企业名称
     */
    public void mergePunishmentData(String candidate) {
        ArchivesBo bo = new ArchivesBo();
        bo.setKeyword(candidate);

        JSONObject jo = skyClientService.query(bo, SkyEyeProperties.PUNISHMENT_INFO);

        if (jo.isEmpty() || !jo.containsKey("total") || jo.getInt("total") == 0) {
            return;
        }

        JSONArray array = jo.getJSONArray("items");
        ObjectMapper mapper = new ObjectMapper();

        try {
            List<SkyPunishment> list = mapper.readValue(array.toString(), new TypeReference<>() {});
            //把以前的数据删除
            punishmentMapper.deleteByCompanies(candidate);
            //重新插入新数据
            list = list.stream().peek(data -> data.setCompanyName(candidate)).toList();
            punishmentMapper.insertBatch(list);
        } catch (Exception e) {
            log.error("获取行政处罚数据失败", e);
        }
    }

    /**
     * merge企业脸谱信息，查找企业关联的人员和企业，并存储到node和relationship
     * @param candidate 企业名称
     */
    public void mergeCompanyFaceData(String candidate) {
        //根据candidate查询数据
        ArchivesBo bo = new ArchivesBo();
        bo.setKeyword(candidate);

        JSONObject data = skyClientService.query(bo, SkyEyeProperties.COMPANY_FACE);

        if(data != null && !data.isEmpty()) {
            saveRelations(data.getJSONArray("relationships"));
            saveNodes(data.getJSONArray("nodes"));
        }
    }

    /**
     * json转企业信息
     * @param data json数据
     * @param info 企业类
     * @return 企业类
     */
    private WbCompanyInfo jsonToCompanyInfo(JSONObject data, WbCompanyInfo info) {
        if (info == null) {
            info = new WbCompanyInfo();
            info.setId(Long.parseLong(data.getStr("id")));
            info.setName(data.getStr("name"));
            info.setStatus("0");
            info.setBlackStatus("0");
            info.setCreateBy(1L);
            info.setUpdateBy(1L);
            info.setCreateTime(new Date());
        }

        info.setSkyId(Long.parseLong(data.getStr("id")));
        info.setRegStatus(data.getStr("regStatus"));
        info.setAddress(data.getStr("regLocation"));
        info.setLegalRepresentative(data.getStr("legalPersonName"));
        info.setContactEmail(data.getStr("email"));
        info.setWebsite(data.getStr("websiteList"));
        info.setContactPhone(data.getStr("phoneNumber"));
        info.setContactPerson(data.getStr("legalPersonName"));
        info.setRegistrationNumber(data.getStr("regNumber"));
        info.setCapital(data.getStr("regCapital"));
        info.setBusinessModel(data.getStr("compForm"));
        info.setCurrency(data.getStr("regCapitalCurrency"));
        JSONObject jo = data.getJSONObject("industryAll");
        info.setIndustry(jo.isEmpty()?"":(jo.containsKey("categoryMiddle")?jo.getStr("categoryMiddle"):""));
        info.setDescription(data.getStr("businessScope"));
        info.setUnifiedSocialCreditCode(data.getStr("creditCode"));
        info.setRemark(data.getStr("tags"));
        info.setFoundationDate(DateUtil.date(data.getLong("estiblishTime")).toDateStr());
        info.setUpdateBy(1L);
        info.setUpdateTime(new Date());

        return info;
    }

    /**
     * 查询天眼查数据
     * @param bo 查询条件
     * @param path 路径
     * @param type 类型
     * @return 返回list
     */
    private List<JSONObject> queryAbnormal(ArchivesBo bo, String path, String type) {
        JSONObject jo = skyClientService.query(bo, path);

        System.out.println(jo.toString());
        if (jo.isEmpty() || jo.getInt("total") == 0) {
            return new ArrayList<>();
        }

        return toArray(jo.getJSONArray("items"), type);
    }

    /**
     * 数据转list
     * @param array 数据集
     * @param type 类型
     * @return 类型
     */
    private List<JSONObject> toArray(JSONArray array, String type) {
        return array.stream().map(data -> {
            JSONObject jo3 = (JSONObject) data;
            jo3.set("dataType", type);
            return jo3;
        }).toList();
    }

    private void saveRelations(JSONArray relationships) {
        List<SkyRelationship> list = new ArrayList<>();

        for(int j = 0; j < relationships.size(); j++) {
            JSONObject relationship = relationships.getJSONObject(j);
            JSONObject properties = relationship.getJSONObject("properties");

            SkyRelationship skyRelationship = new SkyRelationship();
            skyRelationship.setId(Long.parseLong(relationship.getStr("id")));
            skyRelationship.setStartNode(relationship.getStr("startNode"));
            skyRelationship.setEndNode(relationship.getStr("endNode"));
            skyRelationship.setDataType(relationship.getStr("type"));
            skyRelationship.setName(getLabelString(properties.getJSONArray("labels")));
            skyRelationship.setPercent(properties.getStr("percent"));

            list.add(skyRelationship);
        }

        relationshipMapper.insertOrUpdateBatch(list);
    }

    private void saveNodes(JSONArray nodes) {
        List<SkyNode> list = new ArrayList<>();
        //node存储
        for (int j = 0; j < nodes.size(); j++) {
            JSONObject node = nodes.getJSONObject(j);
            JSONObject properties = node.getJSONObject("properties");

            SkyNode skyNode = new SkyNode();
            skyNode.setId(Long.parseLong(node.getStr("id")));
            skyNode.setCode(node.getStr("id"));
            skyNode.setName(properties.getStr("name"));
            skyNode.setLogoUrl(properties.getStr("logo"));
            skyNode.setDataType(getLabelString(node.getJSONArray("labels")));

            list.add(skyNode);
        }

        nodeMapper.insertOrUpdateBatch(list);
    }

    /**
     * 获取数组
     * @param labels 标签
     * @return 标签字符串
     */
    private static String getLabelString(JSONArray labels) {
        if(labels == null || labels.isEmpty()) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        for (Object label : labels) {
            if (!sb.isEmpty()) {
                sb.append(",");
            }

            sb.append(label.toString());
        }

        return sb.toString();
    }

    /* 组装供应商数据使用  */

    /**
     * 组装导出数据
     * @param bo 查询条件
     * @param voMap 基础风险信息
     * @return
     */
    private List<WbCandidateListRiskVo> assembleVendorData(SkyBagBo bo, Map<String, WbCandidateListRiskVo> voMap) {
        List<SkyRelationshipVo> start = relationshipMapper.selectRelationshipListByStartNode(bo);
        List<SkyRelationshipVo> end = relationshipMapper.selectRelationshipListByEndNode(bo);
        //包内企业编码
        List<String> nodeList = new ArrayList<>(Arrays.stream(bo.getCandidateCode().replaceAll("'","").split(",")).toList());

        vendorRelate(start, end, nodeList, voMap);

        List<WbCandidateListRiskVo> voList = voMap.values().stream().toList();

        vendorSame(voMap);

        return voMap.values().stream().toList();
    }

    /**
     * 判断是否亲属关系
     */
    private void vendorRelate(List<SkyRelationshipVo> startRelationshipList, List<SkyRelationshipVo> endRelationshipList, List<String> nodeList, Map<String, WbCandidateListRiskVo> voMap) {
        //开始节点后面接的肯定是公司，所以判断时只需要在亲属关系中使用
        for (SkyRelationshipVo start : startRelationshipList) {
            //当关系节点的下一步包含在包内企业编码时，表明这个是父子关系
            //start是一个公司，所以不存在下一节点是人的情况
            if (nodeList.contains(start.getEndNode())) {
                //开始节点对应的节点是结束节点，表明是end为子公司
                voMap.get(start.getStartNode()).setParent(start);
            }

            //
            for (SkyRelationshipVo end : endRelationshipList) {
                //当关系节点的下一步和关系节点的上一步相等时，表明这个是祖孙关系
                //start是一个公司，所以不存在下一节点是人的情况
                if (start.getEndNode().equals(end.getStartNode())) {
                    voMap.get(start.getStartNode()).setGrantParent(start, end);
                }
            }
        }

        //兄弟关系使用
        for (SkyRelationshipVo start : endRelationshipList) {
            for (SkyRelationshipVo end : endRelationshipList) {
                //同一条数据，执行下一条
                if (start.getStartNode().equals(end.getStartNode()) && start.getEndNode().equals(end.getEndNode())) {
                    continue;
                }

                //当关系节点的上一步和关系节点的上一步相等时，表明是兄弟关系，可能是有同一股东或同一母公司
                if (start.getStartNode().equals(end.getStartNode())) {
                    voMap.get(start.getEndNode()).setSame(start, end);
                }
            }
        }
    }

    private Map<String, WbCandidateListRiskVo> vendorSame(Map<String, WbCandidateListRiskVo> voMap) {
        List<WbCandidateListRiskVo> voList = voMap.values().stream().toList();
        //取法人做一个map
        //取邮箱做一个map
        //取注册地址做一个map
        //取企业联系方式做一个map
        //取股东做一个map
        Map<String, List<String>> legalPersonList = new HashMap<>();
        Map<String, List<String>> mailList = new HashMap<>();
        Map<String, List<String>> addressList = new HashMap<>();
        Map<String, List<String>> contactList = new HashMap<>();
        Map<String, String> allInvestList = new HashMap<>();
        Map<String, String> candidateCodeMap = new HashMap<>();

        voList.stream().peek(vo -> {
            candidateCodeMap.put(vo.getCandidateCode(), vo.getCandidate());

            if(StringUtils.isNotEmpty(vo.getLegalRepresentative())) {
                if(!legalPersonList.containsKey(vo.getLegalRepresentative())) {
                    legalPersonList.put(vo.getLegalRepresentative(), new ArrayList<>());
                }

                legalPersonList.get(vo.getLegalRepresentative()).add(vo.getCandidateCode());
            }

            if(StringUtils.isNotEmpty(vo.getContactEmail())) {
                if (!mailList.containsKey(vo.getContactEmail())) {
                    mailList.put(vo.getContactEmail(), new ArrayList<>());
                }

                mailList.get(vo.getContactEmail()).add(vo.getCandidateCode());
            }


            if(StringUtils.isNotEmpty(vo.getAddress())) {
                if(!addressList.containsKey(vo.getAddress())) {
                    addressList.put(vo.getAddress(), new ArrayList<>());
                }

                addressList.get(vo.getAddress()).add(vo.getCandidateCode());
            }

            if(StringUtils.isNotEmpty(vo.getContactPhone())) {
                if(!contactList.containsKey(vo.getContactPhone())) {
                    contactList.put(vo.getContactPhone(), new ArrayList<>());
                }

                contactList.get(vo.getContactPhone()).add(vo.getCandidateCode());
            }

            allInvestList.put(vo.getCandidateCode(), vo.getInvest());
        });

        //遍历voList
            //判断法人
            //判断股东
            //判断最终受益人
        for(List<String> list : legalPersonList.values()) {
            if(list.size() == 1) {
                continue;
            }

            for(String candidateCode : list) {
                voMap.get(candidateCode).setSameLegalPerson(list, candidateCodeMap);
            }
        }

        for(List<String> list : mailList.values()) {
            if(list.size() == 1) {
                continue;
            }

            for(String candidateCode : list) {
                voMap.get(candidateCode).setSameMail(list, candidateCodeMap);
            }
        }

        for(List<String> list : addressList.values()) {
            if(list.size() == 1) {
                continue;
            }

            for(String candidateCode : list) {
                voMap.get(candidateCode).setSameAddress(list, candidateCodeMap);
            }
        }

        for(List<String> list : contactList.values()) {
            if(list.size() == 1) {
                continue;
            }

            for(String candidateCode : list) {
                voMap.get(candidateCode).setSameContact(list, candidateCodeMap);
            }
        }

        return voMap;
    }
}
